package com.example.jasonrpc.client.simple;

import com.example.jasonrpc.client.TransportSelector;
import com.example.jasonrpc.common.ReflectionUtils;
import com.example.jasonrpc.proto.Peer;
import com.example.jasonrpc.registry.RegistryDirectory;
import com.example.jasonrpc.transport.TransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RandomTransportSelector implements TransportSelector {
    private static final Logger log = LoggerFactory.getLogger(RandomTransportSelector.class);
    private List<TransportClient> clients;

    public RandomTransportSelector() {
        this.clients = new ArrayList<>();
    }

    @Override
    public synchronized void init(List<RegistryDirectory> directories, int count, Class<? extends TransportClient> clazz) {
        count = Math.max(count, 1);
        List<Peer> peers = directories.get(0).getPeers();
        for (Peer peer : peers) {
            for (int i = 0; i < count; i++) {
                TransportClient client = ReflectionUtils.newInstance(clazz);
                client.connect(peer);
                clients.add(client);
            }
            log.info("connect server: " + peer);
        }
    }

    @Override
    public synchronized TransportClient select(String serviceClass) {
        int n = new Random().nextInt(clients.size());
        return clients.remove(n);
    }

    @Override
    public synchronized void release(TransportClient client, String serviceClass) {
        clients.add(client);
    }

    @Override
    public synchronized void close() {
        for (TransportClient client : clients) {
            client.close();
        }
        clients.clear();
    }
}
